package cwd.hcn.com.getotgpath;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;


public class MainActivity extends Activity {

    private TextView mTvUsbPath1 = null;
    private TextView mTvSdcardPath1 = null;
    private TextView mTvUsbPath2 = null;
    private TextView mTvSdcardPath2 = null;
    private TextView mTvPath = null;
    private Button bt_test = null;
    private String usbpath = null;
    private String sdcard = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTvUsbPath1 = (TextView)findViewById(R.id.tv_usb_path1);
        mTvSdcardPath1 = (TextView)findViewById(R.id.tv_sdcard_path1);
        mTvUsbPath2 = (TextView)findViewById(R.id.tv_usb_path2);
        mTvSdcardPath2 = (TextView)findViewById(R.id.tv_sdcard_path2);
        mTvPath = (TextView)findViewById(R.id.tv_path);
        bt_test = (Button)findViewById(R.id.test);
        bt_test.setOnClickListener(new View.OnClickListener() {
            @TargetApi(Build.VERSION_CODES.N)
            @Override
            public void onClick(View view) {
                //获取外置存储详情
//                getDiskInfo();
//                getOTGPath();
                String[] path1 = StorageUtils.getDiskInfo(MainActivity.this);
                mTvUsbPath1.setText("usb1 = " + path1[0]);
                mTvSdcardPath1.setText("sdcard1 = " + path1[1]);
                String[] path2 = StorageUtils.getExStoragePath(MainActivity.this);
                mTvUsbPath2.setText("usb2 = " + path2[1]);
                mTvSdcardPath2.setText("sdcard2 = " + path2[0]);
//                StatFs statFs = new StatFs(path2[1]);
//                long avaibleSize = statFs.getAvailableBytes();
//                long totalSize = statFs.getTotalBytes();
//                mTvPath.setText("可用: " + avaibleSize + "，总量: " + totalSize);

                List<StorageVolume> path = StorageUtils.getStoragePath(MainActivity.this);
                for (int i = 0; i < path.size(); i++) {
                    StorageVolume storageVolume = path.get(i);
                    String state = storageVolume.getState();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    mTvPath.setText("path.size = " + path.size() + ", index = " + i + ", state: " + state);
                }
            }
        });


        //获取usb连接的外置设备
        //showUsbDev();
        //获取usb外置存储详情
        getDiskInfo();
        Log.e("test","usbpath = "+usbpath);
        Log.e("test","sdcard = "+sdcard);
        for(DiskInfo info : mDiskList){
            Log.e("test", "Disk Name : " + info.name + "\n"
                    + "Disk diskId : " + info.diskId + "\n");
            for(DiskPartition partition : info.diskPartitions) {
                Log.e("test", "\tPartition Name : " + partition.name + "\n"
                        + "\tPartition diskId : " + partition.diskId + "\n"
                        + "\tPartition partitionId : " + partition.partitionId + "\n"
                        + "\tPartition Path : " + partition.path + "\n"
                        + "\tPartition Total Size : " + partition.totalSize + "\n"
                        + "\tPartition Avlable Size: " + partition.avlableSize + "\n"
                );
            }
        }

    }

    //private List mDiskList = new ArrayList();
    List<DiskInfo> mDiskList = new ArrayList<DiskInfo>();
    public void getDiskInfo() {
        StorageManager mstorageManager = (StorageManager)this.getApplicationContext().getSystemService(Context.STORAGE_SERVICE);
        try {
            Method methodGetDisks = StorageManager.class.getMethod("getDisks");
            Method methodGetStorageVolumes = StorageManager.class.getMethod("getVolumeList");
            Method getVolumeById = StorageManager.class.getMethod("findVolumeById", String.class);

            StorageVolume[] storageVolumes = (StorageVolume[]) methodGetStorageVolumes.invoke(mstorageManager);
            List disks = (List) methodGetDisks.invoke(mstorageManager);

            //DiskInfo
            Class<?> diskIndoClass = Class.forName("android.os.storage.DiskInfo");
            Method mGetDiskId = diskIndoClass.getMethod("getId");
            Field diskName = diskIndoClass.getField("label");

            //StorageVolume
            Class<?> storageVolumeClass = Class.forName("android.os.storage.StorageVolume");
            Method mGetStorageVolId = storageVolumeClass.getMethod("getId");
            Method mGetStorageVolDescription = storageVolumeClass.getMethod("getDescription", Context.class);
            Method mGetStorageVolPath = storageVolumeClass.getMethod("getPath");
            Method isRemovable = storageVolumeClass.getMethod("isRemovable");
            Method getVolumeState = StorageManager.class.getMethod("getVolumeState", String.class);

            //VolumeInfo
            Class<?> volumeClass = Class.forName("android.os.storage.VolumeInfo");
            Method volumeDiskId = volumeClass.getMethod("getDiskId");

            for(int i = 0; i < disks.size(); i++) {
                DiskInfo diskInfo = new DiskInfo();
                Parcelable parcelable = (Parcelable) disks.get(i);
                diskInfo.diskId = (String) mGetDiskId.invoke(parcelable);
                Log.e("test", "diskid : " + diskInfo.diskId);
                String des = (String) diskName.get(parcelable);
                Log.e("test", "diskName : " + des);
                diskInfo.name = des;
                mDiskList.add(diskInfo);
            }

            for(int j = 0; j < storageVolumes.length; j++) {
                DiskPartition partition = new DiskPartition();
                StorageVolume storageVolume = storageVolumes[j];
                partition.partitionId = (String) mGetStorageVolId.invoke(storageVolume);
                if("emulated".equals(partition.partitionId)) { continue; }
                partition.name = (String) mGetStorageVolDescription.invoke(storageVolume, this);
                partition.path = (String) mGetStorageVolPath.invoke(storageVolume);
                Boolean removeAble = ((Boolean) isRemovable.invoke(storageVolume)).booleanValue();
                String state = (String) getVolumeState.invoke(mstorageManager, partition.path);
                if("mounted".equals(state) && removeAble) {
                    partition.diskId = (String) volumeDiskId.invoke(getVolumeById.invoke(mstorageManager, partition.partitionId));
                    for(DiskInfo diskInfo : mDiskList) {
                        if(diskInfo.diskId.equals(partition.diskId)) {
                            getStorageBlockInfo(partition);
                            diskInfo.diskPartitions.add(partition);
                            Log.e("test", "partition.name : " + partition.name);
                            Log.e("test", "partition.diskId : " + partition.diskId);
                            Log.e("test", "partition.path : " + partition.path);
                            String partitionId = partition.diskId;
                            String[] idSplit = partitionId.split(":");
                            if (idSplit != null && idSplit.length == 2) {
                                if (idSplit[1].startsWith("8,")) {
                                    usbpath =  partition.path;
                                }else{
                                    sdcard =  partition.path;
                                }
                            }
                        }
                    }
                }
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    public class DiskInfo {
        public String diskId;
        public String name;
        //public ArrayList diskPartitions = new ArrayList<>();
        public ArrayList<DiskPartition> diskPartitions = new ArrayList<DiskPartition>();
    }

    public class DiskPartition{
        public String name;
        public String partitionId;
        public String diskId;
        public long totalSize;
        public long avlableSize;
        public String path;
    }

    public static void getStorageBlockInfo(DiskPartition info) {
        if(TextUtils.isEmpty(info.path))
            return;
        android.os.StatFs statfs = new android.os.StatFs(info.path);
        long nBlocSize = statfs.getBlockSizeLong();
        long blockCountLong = statfs.getBlockCountLong();
        long nAvailaBlock = statfs.getAvailableBlocksLong();
        info.totalSize = blockCountLong * nBlocSize;
        info.avlableSize = nBlocSize * nAvailaBlock;
    }

    public void getOTGPath() {
        StorageManager mstorageManager = (StorageManager) this.getApplicationContext().getSystemService(Context.STORAGE_SERVICE);
        try {
            //DiskInfo
            Class<?> diskIndoClass = Class.forName("android.os.storage.DiskInfo");
            Method isUsb = diskIndoClass.getMethod("isUsb");
            Method isSd = diskIndoClass.getMethod("isSd");
            //VolumeInfo
            Class<?> volumeClass = Class.forName("android.os.storage.VolumeInfo");
            Method volumeDisk = volumeClass.getMethod("getDisk");
            Method fsUuid = volumeClass.getMethod("getFsUuid");
            Method path = volumeClass.getMethod("getPath");

            Method getVolumes = StorageManager.class.getDeclaredMethod("getVolumes");
            List volumeInfoList = (List) getVolumes.invoke(mstorageManager);
            for(int i= 0 ;i<volumeInfoList.size();i++){
                //反射得到diskInfo,并判断是不是usb
                if(volumeDisk.invoke(volumeInfoList.get(i)) != null && (boolean)isUsb.invoke(volumeDisk.invoke(volumeInfoList.get(i)))){
                    String path_usb = "mnt/media_rw/"+fsUuid.invoke(volumeInfoList.get(i));
                    Log.e("willie","usb path::"+path_usb);
//                    Log.e("willie","sdcard path_path::"+path.invoke(volumeInfoList.get(i)));
//                    tv_msg1.setText("usb:"+path_usb);
                    Log.e("willie","fsUuid::"+fsUuid.invoke(volumeInfoList.get(i)));
                } else if(volumeDisk.invoke(volumeInfoList.get(i)) != null && (boolean)isSd.invoke(volumeDisk.invoke(volumeInfoList.get(i)))){
                    String path_sdcard =""+path.invoke(volumeInfoList.get(i));
                    Log.e("willie","sdcard path::"+path_sdcard);
//                    tv_msg2.setText("sdcard:"+path_sdcard);
                    Log.e("willie","fsUuid::"+fsUuid.invoke(volumeInfoList.get(i)));
                } else{
                    Log.e("willie","other::"+path.invoke(volumeInfoList.get(i)));
                }
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
